/**
 * PHOSIDE: PHosphorylation Site IDentification Engine.
 * Copyright 2009 Digital Biology Lab, University of Missouri.
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 3 of the License, or (at your option) any later
 * version. <p/> This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more
 * details.
 */

package phoside.data.feature.model;

import org.apache.commons.lang.StringUtils;

import phoside.Protein;

import phoside.util.StaticFinalValues;

/**
 *
 * @author gjj
 */
public class InstanceUtil {

    public static String extractSurroundingSequence(Instance instance, int windowOffset) {
        return extractSurroundingSequence(instance, windowOffset, true);
    }
    
    public static String extractSurroundingSequence(Instance instance, int windowOffset,
            boolean appendTerminals) {
        return extractSurroundingSequence(instance, windowOffset, windowOffset,
                appendTerminals, false);
    }

    public static String extractSurroundingSequence(Instance instance, int windowOffset,
            boolean appendTerminals, boolean markSites) {
        return extractSurroundingSequence(instance, windowOffset, windowOffset,
                appendTerminals, markSites);
    }

    public static String extractSurroundingSequence(Instance instance, int leftOffset,
            int rightOffset) {
        return extractSurroundingSequence(instance, leftOffset, rightOffset, true, false);
    }

    /**
     *
     * @param instance
     * @param windowOffset
     * @param appendTerminals
     * @param markSites mart all sites as [pX]
     * @return
     */
    public static String extractSurroundingSequence(Instance instance, int leftOffset,
            int rightOffset, boolean appendTerminals, boolean markSites) {
        if (instance==null)
            throw new IllegalArgumentException();

        if (leftOffset<0 || rightOffset<0)
            throw new IllegalArgumentException();
        
        InstanceTag tag = instance.getInstanceTag();

        Object obj = tag.getTag(StaticFinalValues.INSTANCETAGNAMEPROTEIN);
        if (obj==null || !(obj instanceof Protein)) {
            return null;
        }
        Protein protein = (Protein)obj;

        obj = tag.getTag(StaticFinalValues.INSTANCETAGNAMESITE);
        if (obj==null || !(obj instanceof Integer)) {
            return null;
        }
        int site = (Integer)obj;

        String proSeq = protein.getSequence();
        if (proSeq==null)
            return null;

        int s = site-leftOffset;
        int t = site+rightOffset+1;

        String ret = new String();

        if (s<0) {
            if (appendTerminals) {
                ret += StringUtils.repeat("*", -s);
                s = 0;
            } else {
                return null;
            }
        }

        if (t>proSeq.length()) {
            if (appendTerminals) {
                if (markSites) {
                    ret += extractMarkedPeptide(protein, s, proSeq.length());
                } else {
                    ret += proSeq.substring(s);
                }
                ret += StringUtils.repeat("*", t-proSeq.length());
            } else {
                return null;
            }
        } else {
            if (markSites) {
                ret += extractMarkedPeptide(protein, s, t);
            } else {
                ret += proSeq.substring(s, t);
            }
        }

        return ret;
    }

    private static String extractMarkedPeptide(Protein protein, int start, int end) {
        java.util.TreeSet<Integer> sites = phoside.data.util.PhosphoDataUtil.getSites(protein);
        String seq = protein.getSequence();
        if (sites==null || sites.isEmpty()) {
            return seq.substring(start, end);
        }

        StringBuilder sb = new StringBuilder();
        int s=start;
        for (int site : sites) {
            if (site>=start && site<end) {
                int t=site;
                sb.append(seq.substring(s,t));
                sb.append("[p"+seq.substring(t, t+1)+"]");
                s=site+1;
            }
        }

        if (s<end) {
            sb.append(seq.substring(s, end));
        }

        return sb.toString();
    }
}
